/**
 * 养老金/提前退休提取金额测算系统
 * 基于4%提取率的第一层级测算体系
 */

class RetirementCalculator {
    constructor() {
        this.data = [];
    }

    /**
     * 生成测算表格
     */
    generateTable() {
        const initialYear = parseInt(document.getElementById('initialYear').value);
        const initialValue = parseFloat(document.getElementById('initialValue').value);
        const withdrawalRate = parseFloat(document.getElementById('withdrawalRate').value) / 100;
        const defaultReturnRate = parseFloat(document.getElementById('defaultReturnRate').value) / 100;
        const yearsCount = parseInt(document.getElementById('yearsCount').value);

        this.data = [];
        let currentValue = initialValue;

        for (let i = 0; i < yearsCount; i++) {
            const year = initialYear + i;
            let returnRate = null; // 默认值为null
            let baseValue = currentValue;

            // 第一年使用初始价值，没有"上年回报率"
            if (i === 0) {
                baseValue = initialValue;
                returnRate = null; // 第一年没有"上年回报率"
            } else {
                // 后续年份使用上一年提款后价值 * (1 + 回报率)
                const prevData = this.data[i - 1];
                if (prevData.actualReturnRate !== null) {
                    returnRate = prevData.actualReturnRate;
                } else {
                    returnRate = defaultReturnRate; // 如果没有实际回报率，使用默认值
                }
                baseValue = prevData.afterWithdrawal * (1 + returnRate);
            }

            const baseWithdrawal = baseValue * withdrawalRate;
            const afterWithdrawal = baseValue - baseWithdrawal;

            this.data.push({
                year: year,
                initialValue: baseValue,
                returnRate: returnRate !== null ? returnRate : 0, // 第一年为0，但不显示
                withdrawalRate: withdrawalRate,
                baseWithdrawal: baseWithdrawal,
                afterWithdrawal: afterWithdrawal,
                actualReturnRate: i === 0 ? null : null, // 第一年没有实际回报率
                isEditable: true, // 所有年份的年初价值都可编辑，方便实时更新
                isManuallyEdited: false // 标记该年的年初价值是否被手动编辑过
            });
        }

        this.updateTable();
        this.updateSummary();
    }

    /**
     * 更新表格显示
     */
    updateTable() {
        const tbody = document.getElementById('tableBody');
        tbody.innerHTML = '';

        this.data.forEach((item, index) => {
            const row = document.createElement('tr');
            
            // 年份
            const yearCell = document.createElement('td');
            yearCell.textContent = item.year;
            row.appendChild(yearCell);

            // 年初价值（可编辑）
            const valueCell = document.createElement('td');
            if (item.isEditable) {
                const input = document.createElement('input');
                input.type = 'number';
                input.className = 'editable';
                input.value = item.initialValue.toFixed(2);
                input.step = '1000';
                input.min = '0';
                input.addEventListener('change', (e) => {
                    this.onValueChange(index, 'initialValue', parseFloat(e.target.value));
                });
                valueCell.appendChild(input);
            } else {
                valueCell.textContent = `¥${item.initialValue.toFixed(2)}`;
                valueCell.className = 'readonly';
            }
            row.appendChild(valueCell);

            // 上年回报率（可编辑）
            // 第一年没有"上年"，所以不显示回报率
            const returnCell = document.createElement('td');
            if (index === 0) {
                // 第一年：显示"-"或空，因为第一年没有"上年"
                returnCell.textContent = '-';
                returnCell.className = 'readonly';
            } else {
                // 从第二年开始：显示上年回报率（可编辑）
                const returnInput = document.createElement('input');
                returnInput.type = 'number';
                returnInput.className = 'editable';
                returnInput.value = (item.returnRate * 100).toFixed(2);
                returnInput.step = '0.1';
                returnInput.min = '-100';
                returnInput.max = '100';
                returnInput.addEventListener('change', (e) => {
                    this.onValueChange(index, 'returnRate', parseFloat(e.target.value) / 100);
                });
                returnCell.appendChild(returnInput);
            }
            row.appendChild(returnCell);

            // 提款率
            const withdrawalRateCell = document.createElement('td');
            withdrawalRateCell.textContent = `${(item.withdrawalRate * 100).toFixed(1)}%`;
            withdrawalRateCell.className = 'readonly';
            row.appendChild(withdrawalRateCell);

            // 基础提款
            const withdrawalCell = document.createElement('td');
            withdrawalCell.textContent = `¥${item.baseWithdrawal.toFixed(2)}`;
            withdrawalCell.className = 'positive';
            row.appendChild(withdrawalCell);

            // 提款后价值
            const afterWithdrawalCell = document.createElement('td');
            afterWithdrawalCell.textContent = `¥${item.afterWithdrawal.toFixed(2)}`;
            afterWithdrawalCell.className = 'readonly';
            row.appendChild(afterWithdrawalCell);

            tbody.appendChild(row);
        });

        document.getElementById('calculationTable').style.display = 'table';
    }

    /**
     * 处理值变化
     */
    onValueChange(index, field, newValue) {
        const item = this.data[index];
        
        if (field === 'initialValue') {
            item.initialValue = newValue;
            // 标记该年为手动编辑
            item.isManuallyEdited = true;
            
            // 如果不是第一年，计算实际回报率
            if (index > 0) {
                const prevData = this.data[index - 1];
                // 计算实际回报率： (本年年初价值 - 上年提款后价值) / 上年提款后价值
                item.actualReturnRate = (newValue - prevData.afterWithdrawal) / prevData.afterWithdrawal;
                item.returnRate = item.actualReturnRate;
            } else {
                // 第一年修改年初价值，不影响回报率
                // 但需要清除实际回报率标记
                item.actualReturnRate = null;
            }
        } else if (field === 'returnRate') {
            // 第一年不应该有"上年回报率"，所以不应该修改第一年的回报率
            if (index === 0) {
                // 第一年没有"上年回报率"，忽略修改
                return;
            }
            
            item.returnRate = newValue;
            item.actualReturnRate = newValue;
            
            // 更新年初价值（基于上一年提款后价值和新的回报率）
            if (index > 0) {
                const prevData = this.data[index - 1];
                if (!item.isManuallyEdited) {
                    item.initialValue = prevData.afterWithdrawal * (1 + newValue);
                }
            }
        }

        // 重新计算基础提款和提款后价值
        item.baseWithdrawal = item.initialValue * item.withdrawalRate;
        item.afterWithdrawal = item.initialValue - item.baseWithdrawal;

        // 更新后续年份（自动更新未被手动编辑的年份）
        this.updateSubsequentYears(index);

        // 更新表格显示（会在updateTable中正确显示所有数据）
        this.updateTable();
        this.updateSummary();
    }

    /**
     * 更新后续年份
     * 从startIndex+1年开始，自动更新未被手动编辑的年份
     */
    updateSubsequentYears(startIndex) {
        for (let i = startIndex + 1; i < this.data.length; i++) {
            const prevData = this.data[i - 1];
            const currentData = this.data[i];
            
            // 获取用于计算的回报率
            // 优先使用上一年设置的实际回报率，否则使用上一年显示的回报率
            let returnRate = prevData.actualReturnRate !== null ? prevData.actualReturnRate : prevData.returnRate;
            
            // 如果该年的年初价值未被手动编辑，则根据上一年自动计算
            if (!currentData.isManuallyEdited) {
                // 自动计算年初价值：上一年的提款后价值 * (1 + 回报率)
                currentData.initialValue = prevData.afterWithdrawal * (1 + returnRate);
                // 更新回报率（使用上一年设置的回报率）
                currentData.returnRate = returnRate;
                // 清除实际回报率标记（因为这是自动计算的）
                currentData.actualReturnRate = null;
            } else {
                // 如果该年的年初价值已被手动编辑，保持其值不变
                // 但需要重新计算实际回报率（因为上一年的提款后价值可能已变化）
                // 重新计算实际回报率： (本年年初价值 - 上年提款后价值) / 上年提款后价值
                currentData.actualReturnRate = (currentData.initialValue - prevData.afterWithdrawal) / prevData.afterWithdrawal;
                currentData.returnRate = currentData.actualReturnRate;
            }

            // 重新计算基础提款和提款后价值（无论是否被手动编辑，都需要重新计算）
            currentData.baseWithdrawal = currentData.initialValue * currentData.withdrawalRate;
            currentData.afterWithdrawal = currentData.initialValue - currentData.baseWithdrawal;
        }
    }

    /**
     * 更新摘要信息
     */
    updateSummary() {
        if (this.data.length === 0) return;

        const currentData = this.data[0];
        document.getElementById('currentValue').textContent = `¥${currentData.initialValue.toFixed(2)}`;
        document.getElementById('currentWithdrawal').textContent = `¥${currentData.baseWithdrawal.toFixed(2)}`;
        document.getElementById('afterWithdrawal').textContent = `¥${currentData.afterWithdrawal.toFixed(2)}`;
        document.getElementById('summarySection').style.display = 'grid';
    }

    /**
     * 生成随机收益率
     * 生成指定年数的随机收益率，平均值为5%，范围在-20%到+30%之间
     */
    generateRandomReturns() {
        if (this.data.length === 0) {
            alert('请先生成测算表！');
            return;
        }

        const yearsCount = this.data.length;
        const targetAverage = 5; // 目标平均值5%
        const minReturn = -20; // 最小收益率-20%
        const maxReturn = 30; // 最大收益率30%
        
        // 第一年不需要回报率（因为第一年没有"上年"）
        // 从第二年开始生成随机收益率
        const returnCount = yearsCount - 1; // 需要生成的年数（排除第一年）
        
        if (returnCount <= 0) {
            alert('至少需要2年才能生成随机收益率！');
            return;
        }
        
        // 生成随机收益率数组，范围在-20%到+30%之间
        // 确保每年生成的值都不同（避免重复值）
        let returns = [];
        const usedValues = new Set(); // 用于跟踪已生成的值（保留两位小数）
        const minDifference = 0.01; // 最小差值（0.01%），确保每个值都不同
        
        for (let i = 0; i < returnCount; i++) {
            let randomReturn;
            let attempts = 0;
            const maxAttempts = 1000; // 最大尝试次数，避免无限循环
            
            // 生成一个不重复的随机值
            do {
                randomReturn = Math.random() * (maxReturn - minReturn) + minReturn;
                // 四舍五入到两位小数，用于比较
                const roundedValue = Math.round(randomReturn * 100) / 100;
                attempts++;
                
                // 如果值已存在，继续生成
                if (usedValues.has(roundedValue)) {
                    randomReturn = null;
                } else {
                    usedValues.add(roundedValue);
                }
            } while (randomReturn === null && attempts < maxAttempts);
            
            // 如果尝试次数过多，使用微调方法
            if (randomReturn === null) {
                // 生成一个基础值
                randomReturn = Math.random() * (maxReturn - minReturn) + minReturn;
                const roundedValue = Math.round(randomReturn * 100) / 100;
                
                // 如果值已存在，微调它
                if (usedValues.has(roundedValue)) {
                    // 尝试向上或向下微调
                    let adjustedValue = roundedValue;
                    let direction = 1; // 1表示向上，-1表示向下
                    let step = minDifference;
                    
                    while (usedValues.has(adjustedValue) && step < 1) {
                        adjustedValue = roundedValue + (direction * step);
                        if (adjustedValue < minReturn || adjustedValue > maxReturn) {
                            direction *= -1; // 改变方向
                            step += minDifference;
                            adjustedValue = roundedValue + (direction * step);
                        }
                        step += minDifference;
                    }
                    
                    randomReturn = adjustedValue;
                    usedValues.add(adjustedValue);
                } else {
                    usedValues.add(roundedValue);
                }
            }
            
            returns.push(randomReturn);
        }
        
        // 计算当前总和和目标总和
        let currentSum = returns.reduce((a, b) => a + b, 0);
        const targetSum = targetAverage * returnCount;
        let diff = targetSum - currentSum;
        
        // 保存原始随机值，用于权重计算（保持相对差异）
        const originalValues = [...returns];
        
        // 使用迭代调整算法，确保平均值接近目标值
        // 关键：每次调整后都要确保所有值仍然不同
        let iterations = 0;
        const maxIterations = 200;
        const tolerance = 0.1; // 允许的总和误差
        
        while (Math.abs(diff) > tolerance && iterations < maxIterations) {
            // 找出所有可以调整的值（不在边界上的值）
            const adjustableIndices = [];
            
            for (let i = 0; i < returns.length; i++) {
                // 检查是否在边界上（留出小的余量）
                const margin = 0.01;
                if (returns[i] > (minReturn + margin) && returns[i] < (maxReturn - margin)) {
                    adjustableIndices.push(i);
                }
            }
            
            if (adjustableIndices.length === 0) {
                // 所有值都在边界上，无法进一步调整
                break;
            }
            
            // 使用渐进式调整，每次只调整一部分差值
            // 使用固定权重（基于原始随机值的差异），而不是每次重新随机
            const adjustmentFactor = 0.15; // 每次调整15%的差值，更渐进
            
            // 计算每个值的权重（基于原始值，保持相对差异）
            let totalWeight = 0;
            const weights = [];
            
            for (const idx of adjustableIndices) {
                // 权重基于原始值与平均值的差异，确保调整时保持相对差异
                const originalValue = originalValues[idx];
                const weight = Math.abs(originalValue - targetAverage) + 0.1; // 确保权重不为0
                weights.push({ index: idx, weight: weight });
                totalWeight += weight;
            }
            
            // 按权重分配调整量
            let actualAdjustment = 0;
            const newValues = new Map(); // 用于跟踪调整后的值，确保不重复
            
            for (const item of weights) {
                const adjustment = (diff * adjustmentFactor * item.weight) / totalWeight;
                let newValue = returns[item.index] + adjustment;
                
                // 确保不超过边界
                if (newValue < minReturn) {
                    newValue = minReturn;
                } else if (newValue > maxReturn) {
                    newValue = maxReturn;
                }
                
                // 确保调整后的值不与其他值重复
                const roundedNewValue = Math.round(newValue * 100) / 100;
                if (newValues.has(roundedNewValue)) {
                    // 如果值已存在，微调它
                    let adjustedValue = newValue;
                    let direction = Math.random() > 0.5 ? 1 : -1;
                    let step = 0.01;
                    let attempts = 0;
                    
                    while (newValues.has(Math.round(adjustedValue * 100) / 100) && attempts < 100) {
                        adjustedValue = newValue + (direction * step);
                        if (adjustedValue < minReturn || adjustedValue > maxReturn) {
                            direction *= -1;
                            step += 0.01;
                            adjustedValue = newValue + (direction * step);
                        }
                        attempts++;
                    }
                    newValue = adjustedValue;
                }
                
                newValues.set(Math.round(newValue * 100) / 100, true);
                actualAdjustment += (newValue - returns[item.index]);
                returns[item.index] = newValue;
            }
            
            // 重新计算总和和差值
            currentSum = returns.reduce((a, b) => a + b, 0);
            diff = targetSum - currentSum;
            iterations++;
            
            // 如果实际调整量很小，说明已经接近边界
            if (Math.abs(actualAdjustment) < 0.01) {
                break;
            }
        }
        
        // 确保所有值都在范围内（强制修正）
        for (let i = 0; i < returns.length; i++) {
            if (returns[i] < minReturn) {
                returns[i] = minReturn;
            } else if (returns[i] > maxReturn) {
                returns[i] = maxReturn;
            }
        }
        
        // 确保调整后的值仍然不同（避免重复值）
        // 检查是否有重复值，如果有，进行微调
        const finalValues = new Set();
        const minDiff = 0.01; // 最小差值
        
        for (let i = 0; i < returns.length; i++) {
            let value = returns[i];
            const roundedValue = Math.round(value * 100) / 100;
            
            // 如果值已存在，微调它
            if (finalValues.has(roundedValue)) {
                // 尝试向上或向下微调
                let adjustedValue = roundedValue;
                let direction = 1;
                let step = minDiff;
                
                while (finalValues.has(adjustedValue) && step < 1) {
                    adjustedValue = roundedValue + (direction * step);
                    if (adjustedValue < minReturn || adjustedValue > maxReturn) {
                        direction *= -1;
                        step += minDiff;
                        adjustedValue = roundedValue + (direction * step);
                    }
                    step += minDiff;
                }
                
                value = adjustedValue;
                returns[i] = value;
            }
            
            finalValues.add(Math.round(value * 100) / 100);
        }
        
        // 计算最终平均值
        const finalSum = returns.reduce((a, b) => a + b, 0);
        const finalAverageCorrected = finalSum / returns.length;
        
        // 验证所有值都在范围内
        const allInRange = returns.every(rate => rate >= minReturn && rate <= maxReturn);
        
        // 验证所有值都不同（保留两位小数）
        const uniqueValues = new Set(returns.map(r => Math.round(r * 100) / 100));
        const allDifferent = uniqueValues.size === returns.length;
        
        if (!allInRange) {
            console.error('错误：部分收益率超出范围！');
        }
        
        if (!allDifferent) {
            console.warn('警告：存在重复的收益率值！');
        }
        
        // 将随机收益率填入数据
        // 关键：确保每个年份的回报率都是我们生成的随机值，不互相覆盖
        // 按顺序更新每个年份，确保年初价值基于上一年正确计算
        for (let i = 0; i < returns.length; i++) {
            const dataIndex = i + 1; // 从第二年开始（索引从1开始）
            if (dataIndex < this.data.length) {
                const returnRate = returns[i] / 100; // 转换为小数（百分比转小数）
                
                // 设置回报率（这是关键：每个年份都有不同的随机值）
                this.data[dataIndex].returnRate = returnRate;
                this.data[dataIndex].actualReturnRate = returnRate;
                // 清除手动编辑标记，因为这是系统自动生成的
                this.data[dataIndex].isManuallyEdited = false;
                
                // 更新年初价值（基于上一年提款后价值和新的回报率）
                // 注意：必须按顺序更新，因为后续年份依赖于前面的年份
                const prevData = this.data[dataIndex - 1];
                this.data[dataIndex].initialValue = prevData.afterWithdrawal * (1 + returnRate);
                
                // 重新计算基础提款和提款后价值
                this.data[dataIndex].baseWithdrawal = this.data[dataIndex].initialValue * this.data[dataIndex].withdrawalRate;
                this.data[dataIndex].afterWithdrawal = this.data[dataIndex].initialValue - this.data[dataIndex].baseWithdrawal;
            }
        }
        
        // 重要：不要调用updateSubsequentYears，因为我们已经为每个年份设置了不同的随机回报率
        // 如果调用updateSubsequentYears，它会基于上一年自动计算下一年，导致值相同
        // 我们已经在上面的循环中按顺序更新了所有年份的数据
        
        // 更新表格显示（统一更新，避免直接操作DOM）
        this.updateTable();
        this.updateSummary();
        
        // 显示统计信息
        const minGenerated = Math.min(...returns);
        const maxGenerated = Math.max(...returns);
        const actualAverage = finalAverageCorrected;
        
        // 验证信息
        const rangeOk = allInRange ? '✓' : '✗';
        const averageOk = Math.abs(actualAverage - targetAverage) < 0.1 ? '✓' : '✗';
        const differentOk = allDifferent ? '✓' : '✗';
        const averageDiff = Math.abs(actualAverage - targetAverage);
        
        // 调试信息：显示前5个值
        const sampleValues = returns.slice(0, Math.min(5, returns.length)).map(r => r.toFixed(2)).join(', ');
        
        let message = `随机收益率生成完成！\n\n`;
        message += `生成年数：${returns.length}年\n`;
        message += `目标收益率：${targetAverage}%\n`;
        message += `实际平均收益率：${actualAverage.toFixed(2)}%\n`;
        message += `平均值差异：${averageDiff.toFixed(2)}% ${averageOk}\n`;
        message += `最小值：${minGenerated.toFixed(2)}%\n`;
        message += `最大值：${maxGenerated.toFixed(2)}%\n`;
        message += `范围检查：${rangeOk} (${minReturn}% 到 ${maxReturn}%)\n`;
        message += `唯一性检查：${differentOk} (每年值都不同)\n`;
        message += `前5个值示例：${sampleValues}%\n`;
        
        if (!allInRange) {
            message += `\n⚠ 警告：部分收益率超出范围！`;
        }
        if (!allDifferent) {
            message += `\n⚠ 警告：存在重复的收益率值！`;
        }
        if (averageDiff > 0.5) {
            message += `\n⚠ 注意：平均值与目标值差异 ${averageDiff.toFixed(2)}%，可能因为边界限制无法完全达到目标值。`;
        }
        
        // 输出到控制台以便调试
        console.log('生成的随机收益率:', returns.map(r => r.toFixed(2)));
        console.log('平均值:', actualAverage.toFixed(2));
        console.log('最小值:', minGenerated.toFixed(2));
        console.log('最大值:', maxGenerated.toFixed(2));
        console.log('唯一值数量:', uniqueValues.size, '总数量:', returns.length);
        console.log('所有值都不同:', allDifferent);
        
        // 检查是否有重复值
        const valueCounts = {};
        returns.forEach(r => {
            const key = r.toFixed(2);
            valueCounts[key] = (valueCounts[key] || 0) + 1;
        });
        const duplicates = Object.entries(valueCounts).filter(([key, count]) => count > 1);
        if (duplicates.length > 0) {
            console.error('发现重复值:', duplicates);
        }
        
        alert(message);
    }
}

// 全局实例
const calculator = new RetirementCalculator();

// 生成表格
function generateTable() {
    calculator.generateTable();
}

// 生成随机收益率
function generateRandomReturns() {
    calculator.generateRandomReturns();
}

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
    console.log('养老金/提前退休提取金额测算系统已加载');
    
    // 可以自动生成一次表格
    // generateTable();
});

